package com.hogofwar.DJbot;

import bsh.*;

import java.io.*;
import java.net.*;
import java.sql.*;
import java.util.*;
import java.util.Date;

import org.jibble.pircbot.*;
import org.python.core.PyObject;
import org.python.util.PythonInterpreter;
import java.util.Properties;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

import javax.activation.DataHandler;
import javax.activation.FileDataSource;
import javax.mail.Authenticator; 
import javax.mail.Message; 
import javax.mail.MessagingException; 
import javax.mail.Multipart;
import javax.mail.PasswordAuthentication; 
import javax.mail.Session; 
import javax.mail.Transport; 
import javax.mail.internet.InternetAddress; 
import javax.mail.internet.MimeBodyPart;
import javax.mail.internet.MimeMessage;   
import javax.mail.internet.MimeMultipart;
public class IRCBase extends PircBot {

	public static String prefix = loadProp("prefix", ";");
	public static String classpre = loadProp("classprefix", "COM_");
	public static String factoidprefix= loadProp("factprefix", ",");
	public static String name = loadProp("name", "Om");
	public static String pass = loadProp("pass");
	public static String classdir = loadProp("dir", "plugins/bin/");
	public static String emailto = loadProp("emailto");
	public static String emailfrom = loadProp("emailfrom");
	public static String emailpass = loadProp("emailpassword");
	public static String emailsmtpserver = loadProp("emailsmtpserver");
	public static String emailsmtpport = loadProp("emailsmtpport");
	protected String server = "";
	public static int messagesreceived = 0;
	public static int factoidsgiven = 0;
	public static int factoidsset = 0;
	public static boolean stfu = false;
	public static int timetilcheck = 1000;
public static int messagesleft = 7;
	public ArrayList<String> al = new ArrayList<String>();

//	public static void main(String[] args) {
//
//		try {
//			IRCBase window = new IRCBase();
//
//			// window.frmJirc.setVisible(true);
//		} catch (Exception e) {
//			e.printStackTrace();
//		}
//
//	}

	/**
	 * Create the application.
	 * 
	 * @throws IrcException
	 * @throws IOException
	 * @throws NickAlreadyInUseException
	 * @throws EvalError
	 */
	public static Interpreter in = new Interpreter();

	public IRCBase(String s2) throws NickAlreadyInUseException, IOException,
			IrcException, EvalError {
server = s2;
		this.setName(name);
		this.setLogin(name);
		this.setVerbose(true);

		connect(s2);
		System.out.println("server: "+getServer());
		sendMessage("NickServ", "identify " + pass);
		setMessageDelay(500);
		in.set("bot", this);

		in.eval("importObject(bot)");

		try {
			FileInputStream fin = new FileInputStream("channels"+getServer()+".dat");
			ObjectInputStream ois = new ObjectInputStream(fin);
			List<String> list = (ArrayList) ois.readObject();

			for (String s : list) {
				al.add(s);
			}

			ois.close();
		} catch (Exception e) {
			e.printStackTrace();
		}
		for (int i = 0; i < al.size(); i++)
			this.joinChannel(al.get(i));
		String input = (new BufferedReader(new InputStreamReader(System.in)))
				.readLine();
		if (input.equalsIgnoreCase("stop")) {
			System.exit(0);
		} else {

			in.eval((new BufferedReader(new InputStreamReader(System.in)))
					.readLine());
			System.out.println("received");
		}
	}

	/**
	 * Initialize the contents of the frame.
	 */
	public static String lastsaid = null;

	public static boolean start = true;

	// System.out.println("Using send!"+ chat.getText());
	// System.out.println("last said is:"+ lastsaid);
	// }

	// ------------Irc commands after this!
	public void log(String channel, String sender, String login,
			String hostname, String message) {
		try {
			Class.forName("org.sqlite.JDBC");
			Connection conn = DriverManager
					.getConnection("jdbc:sqlite:chat.db");
			Statement stat = conn.createStatement();
			// stat.executeUpdate("drop table if exists people;");
			stat.executeUpdate("create table IF NOT EXISTS people (time, name, capsname, message, channel, status, hour, minute, seconds);");
			PreparedStatement prep = conn
					.prepareStatement("insert into people values (?, ?, ?, ?, ?, ?, ?, ?, ?);");

			boolean cont = false;
			boolean isop = false;
			boolean ismaker = false;
			boolean isvoice = false;
			User users[] = getUsers(channel);
			User u = null;
			for (User user : users) {
				if (sender.equals(user.getNick())) {
					u = user;
					break;
				}
			}
			if (u != null) {
				if (u.isOp()) {
					isop = true;
				} else if (u.hasVoice()) {
					isvoice = true;
				}
			}
			String send = "";
			if (isop) {
				send = "@";
			} else if (isvoice) {
				send = "+";

			}
			Calendar cal = new GregorianCalendar();
			prep.setLong(1, System.currentTimeMillis());
			prep.setString(2, sender.toLowerCase());
			prep.setString(3, sender);
			prep.setString(4, message);
			prep.setString(5, channel);
			prep.setString(6, send);
			prep.setInt(7, cal.get(Calendar.HOUR_OF_DAY));
			prep.setInt(8, cal.get(Calendar.MINUTE));
			prep.setInt(9, cal.get(Calendar.SECOND));
			prep.addBatch();

			conn.setAutoCommit(false);
			prep.executeBatch();
			conn.setAutoCommit(true);
			conn.close();
		} catch (ClassNotFoundException e2) {
			// TODO Auto-generated catch block
			e2.printStackTrace();
		} catch (SQLException e2) {
			// TODO Auto-generated catch block
			e2.printStackTrace();
		}
	}

	public void log(String channel, String message) {
		try {
			Class.forName("org.sqlite.JDBC");
			Connection conn = DriverManager
					.getConnection("jdbc:sqlite:chat.db");
			Statement stat = conn.createStatement();
			// stat.executeUpdate("drop table if exists people;");
			stat.executeUpdate("create table IF NOT EXISTS people (time, name, capsname, message, channel, status, hour, minute, seconds);");
			PreparedStatement prep = conn
					.prepareStatement("insert into people values (?, ?, ?, ?, ?, ?, ?, ?, ?);");

			String sender = "*";
			Calendar cal = new GregorianCalendar();
			prep.setLong(1, System.currentTimeMillis());
			prep.setString(2, sender.toLowerCase());
			prep.setString(3, sender);
			prep.setString(4, message);
			prep.setString(5, channel);
			prep.setString(6, "");
			prep.setInt(7, cal.get(Calendar.HOUR_OF_DAY));
			prep.setInt(8, cal.get(Calendar.MINUTE));
			prep.setInt(9, cal.get(Calendar.SECOND));
			prep.addBatch();

			conn.setAutoCommit(false);
			prep.executeBatch();
			conn.setAutoCommit(true);
			conn.close();
		} catch (ClassNotFoundException e2) {
			// TODO Auto-generated catch block
			e2.printStackTrace();
		} catch (SQLException e2) {
			// TODO Auto-generated catch block
			e2.printStackTrace();
		}
	}

	public void onMessage(String channel, String sender, String login,
			String hostname, String message) {
		// if (message.equalsIgnoreCase("time")) {
		// String time = new java.util.Date().toString();
		// sendMessage(channel, sender + ": The time is now " + time);
		// }
		messagesreceived++;
		timetilcheck--;
		if(timetilcheck<=0){
				messagesleft=7;

			System.out.println("Time to check email!");
			timetilcheck=1000;
			if((new File("chat.db")).length()/1024/1024 >10){
			String[] filenames = new String[]{"chat.db"};

			// Create a buffer for reading the files
			byte[] buf = new byte[1024];

			try {
			    // Create the ZIP file
			    String outFilename = "chat.zip";
			    ZipOutputStream out = new ZipOutputStream(new FileOutputStream(outFilename));

			    // Compress the files
			    for (int i=0; i<filenames.length; i++) {
			        FileInputStream in = new FileInputStream(filenames[i]);

			        // Add ZIP entry to output stream.
			        out.putNextEntry(new ZipEntry(filenames[i]));

			        // Transfer bytes from the file to the ZIP file
			        int len;
			        while ((len = in.read(buf)) > 0) {
			            out.write(buf, 0, len);
			        }

			        // Complete the entry
			        out.closeEntry();
			        in.close();
			    }

			    // Complete the ZIP file
			    out.close();
			
			  String to = emailto;
			  final String from = emailfrom;
			  String host = emailsmtpserver;
			  String filename = "chat.zip";
			  String msgText1 = "You have received this log because the log size went over 10mb.";
			  String subject = "Here is your log!";
			  final String password = emailpass;
			  
			  // create some properties and get the default Session
			 
			  Properties props = System.getProperties();
			    props.put("mail.smtp.starttls.enable", "true"); // added this line
			    props.put("mail.smtp.host", host);
			    props.put("mail.smtp.user", from);
			    //props.put("mail.smtp.password", password);
			    props.put("mail.smtp.port", emailsmtpport);
			    props.put("mail.smtp.auth", "true");
	            Authenticator auth = new Authenticator() {

	                @Override
	                protected PasswordAuthentication getPasswordAuthentication() {
	                    return new PasswordAuthentication(from, password);
	                }
	            };

			  Session session = Session.getInstance(props, auth);

		
			      // create a message
			      MimeMessage msg = new MimeMessage(session);
			      msg.setFrom(new InternetAddress(from));
			      InternetAddress[] address = {new InternetAddress(to)};
			      msg.setRecipients(Message.RecipientType.TO, address);
			      msg.setSubject(subject);

			      // create and fill the first message part
			      MimeBodyPart mbp1 = new MimeBodyPart();
			      mbp1.setText(msgText1);

			      // create the second message part
			      MimeBodyPart mbp2 = new MimeBodyPart();

			            // attach the file to the message
			         FileDataSource fds = new FileDataSource(filename);
			      mbp2.setDataHandler(new DataHandler(fds));
			      mbp2.setFileName(fds.getName());

			      // create the Multipart and add its parts to it
			      Multipart mp = new MimeMultipart();
			      mp.addBodyPart(mbp1);
			      mp.addBodyPart(mbp2);

			      // add the Multipart to the message
			      msg.setContent(mp);

			      // set the Date: header
			      msg.setSentDate(new Date());
			      
			      // send the message
			      Transport transport = session.getTransport("smtp");
			      transport.connect (host, 587, from, password);
			      transport.sendMessage(msg, msg.getAllRecipients());
			      transport.close();    
			      System.out.println("Sent email, deleting leftovers.");
			      File db = new File("chat.db");
			      File zip = new File("chat.zip");
//			      db.delete();
//			      zip.delete();
			      System.out.println("DB delete: "+db.delete()+". ZIP delete: "+zip.delete());
			  } 
			  catch (MessagingException mex) 
			  {
			      mex.printStackTrace();
			      Exception ex = null;
			      if ((ex = mex.getNextException()) != null) {
			    ex.printStackTrace();
			      }
			  } catch (FileNotFoundException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}

		}
		}
		log(channel, sender, login, hostname, message);
		if (!sender.equalsIgnoreCase(name)) {
			String split[] = message.split(" ");
			if(!stfu){
			try {
				Class.forName("org.sqlite.JDBC");
				Connection conn = DriverManager
						.getConnection("jdbc:sqlite:tell.db");
				Statement stat = conn.createStatement();
				 stat.executeUpdate("create table IF NOT EXISTS tell (user, message, time, fromuser);");
				ResultSet rs = stat
						.executeQuery("select * from tell where user='"
								+ sender.toLowerCase() + "' ORDER BY time ASC;");
				boolean istrue = true;
				while (rs.next()) {
					if (istrue) {
						sendNotice(sender, "You have some messages:");
						istrue = false;
					}
					long timeInMillis = rs.getLong("time");
					Calendar cal = Calendar.getInstance();
					cal.setTimeInMillis(timeInMillis);
					String hour = ""+cal.get(Calendar.HOUR);
					if(cal.get(Calendar.HOUR)<10){
							hour = String.format("%02d", cal.get(Calendar.HOUR));
						}	
					String minute= ""+cal.get(Calendar.MINUTE);
					if(cal.get(Calendar.MINUTE)<10){
							minute = String.format("%02d", cal.get(Calendar.MINUTE));
						}	
					sendNotice(
							sender,
							rs.getString("message") + " from "
									+ rs.getString("fromuser") + " at "
									+ hour + ":"
									+ minute + " on "
									+ cal.get(Calendar.DAY_OF_MONTH) + "/"
									+ (cal.get(Calendar.MONTH) + 1) + "/"
									+ cal.get(Calendar.YEAR));

				}
				stat.executeUpdate("DELETE FROM tell WHERE user='"
						+ sender.toLowerCase() + "'");
				rs.close();
				conn.close();

			} catch (ClassNotFoundException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (SQLException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			}
			if(!stfu){
			if (split[0].substring(0, 1).equalsIgnoreCase(factoidprefix)) {
				String tosend = "";
				try {
					Class.forName("org.sqlite.JDBC");
					Connection conn = DriverManager
							.getConnection("jdbc:sqlite:factoids.db");
					Statement stat = conn.createStatement();
					ResultSet rs = stat
							.executeQuery("select * from factoids where key='"
									+ split[0].substring(1).toLowerCase()
									+ "' ORDER BY time DESC LIMIT 1;");

					while (rs.next()) {

						tosend = rs.getString("message");
					}
					rs.close();
					conn.close();
				} catch (ClassNotFoundException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				} catch (SQLException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}

				if (!tosend.equalsIgnoreCase("")) {
					factoidsgiven++;
					if(split.length>1){
					int istrue = 1;
					String rest = null;
					for(String s: split){
						if(istrue != 0){
							istrue--;
						}else{
							if(rest !=null)
								rest = rest+" "+s.trim();
							else
								rest = s.trim();
						}
					}
					tosend = tosend.replace( "$inp" ,rest );
					}
					tosend = tosend.replace( "$user" ,sender );
					
					sendMessage(channel, tosend);
				}
			
			} else if ((split[0].equalsIgnoreCase(prefix + "help") && split.length == 1)
					|| (split[0].toLowerCase().contains(name.toLowerCase())
							&& split[1].toLowerCase().contains(
									"help".toLowerCase()) && split.length == 2)) {

				help(sender);

			} else if ((split[0].equalsIgnoreCase(prefix + "help") && split.length > 1)
					|| (split[0].toLowerCase().contains(name.toLowerCase())
							&& split[1].toLowerCase().contains(
									"help".toLowerCase()) && split.length > 2)) {
				String commandhelp = null;
				if ((split[0].toLowerCase().contains(name.toLowerCase())
						&& split[1].toLowerCase()
								.contains("help".toLowerCase()) && split.length > 2)) {
					commandhelp = split[2].toLowerCase();
				} else {
					commandhelp = split[1].toLowerCase();
				}
				help(sender, commandhelp);
			} else if (message.substring(0, 1).equalsIgnoreCase(prefix)
					|| split[0].toLowerCase().contains(name.toLowerCase())) {

				String message2 = null;
				if (split[0].toLowerCase().contains(name.toLowerCase())) {
					// System.out.println(name.length());
					// System.out.println(name.substring(0, name.length()));
					// System.out.println("got here!");
					if (split.length != 1) {
						// System.out.println("and here!");
						String[] extra2 = Arrays.copyOfRange(split, 1,
								split.length);
						// System.out.println("THIS IS "+extra2[0]);

						for (String s : extra2) {
							if (message2 == null) {
								message2 = s;
							} else {
								message2 = message2 + " " + s;
							}
							// System.out.println(message2);
						}
						// System.out.println("got here!");

						commandexe(message2, channel, sender, hostname, true, false);
					}
				} else {
					// System.out.println("or here!");
					message2 = message;
					// System.out.println("message 2 is:"+ message2);
					commandexe(message2, channel, sender, hostname, true, true);
				}
				// commandexe(message2, channel, sender, true , false);

				// if(exists("com.hogofwar.DJbot.plugins.COM_" + command)){

			}
			// sendMessage("#lactic", "length: "+split.length);
			// sendMessage("#lactic", "i: "+i);
		
		}else{
			if(split[0].equalsIgnoreCase(prefix+"stfu") || split[0].equalsIgnoreCase(prefix+"gtfo")|| split[0].equalsIgnoreCase(prefix+"kthx")||split[0].equalsIgnoreCase(prefix+"quiet")||split[0].equalsIgnoreCase(prefix+"shutit")){
				stfu = false;
				String tosend = "At last, I can talk!";
				sendNotice(sender,  tosend);
				
			}
		}
		}
		// }
	}

	public void commandexe(String message, String channel, String sender, String hostname,
			boolean usename, boolean sub) {

		// System.out.println("also got here: " +message);

		String split[] = message.split(" ");
		String command;
		if (sub) {
			command = split[0].substring(1);
			// System.out.println("this be here: " +command);
		} else {
			// System.out.println("2also got here: " +split[0]);
			command = split[0];
			// System.out.println("tsalso got here: " +command);
		}

		command = command.toLowerCase();
		// System.out.println("command got here "+command);
		String extra[] = null;
		if (split.length != 0) {
			extra = Arrays.copyOfRange(split, 1, split.length);
		}
		File dir2 = new File(classdir);
		// sendNotice(sender,"-- Help Commencing --");
		File checkifclassexists = new File(classdir + classpre + "" + command
				+ ".class");
		boolean exists = checkifclassexists.exists();
		File checkifclassexists2 = new File(classdir + classpre + "" + command
				+ ".py");
		boolean exists2 = checkifclassexists2.exists();
		if (!exists && !exists2) {
			HashMap<String, String> hm = new HashMap<String, String>();
			File[] list = dir2.listFiles();
			for (File s : list) {
				// System.out.println(s.toString());
				if (s.getName().lastIndexOf('.') > 0) {
					if (s.getName().contains("COM_")
							&& s.getName().contains(".class")) {
						// System.out.println(s.getName().substring(0,
						// s.getName().lastIndexOf('.')));
						BasePlugin pluginget = PluginLoad.getPlugin(s.getName()
								.substring(0, s.getName().lastIndexOf('.')));
						// System.out.println(s.toString());
						String ali = pluginget.aliases();
						// System.out.println(s.getName().substring(0,
						// s.getName().lastIndexOf('.'))+": "+ali);
						if (ali != null) {
							String alisplit[] = ali.split(",");
							for (String s2 : alisplit) {
								s2 = s2.trim();
								hm.put(s2,
										new String(s.getName().substring(4,
												s.getName().lastIndexOf('.'))));
							}
						}

					} else {
						if (s.getName().contains("COM_")
								&& s.getName().contains(".py")) {
							PythonInterpreter interp = new PythonInterpreter();
							Writer out = new StringWriter();
							interp.setOut(out);

							interp.execfile(s.toString());
							PyObject ali = interp.get("aliases");
							String ali2 = ali.asString();
							if (ali2 != null) {
								String[] aliarray = ali2.split(",");
								for (String s2 : aliarray) {
									s2 = s2.trim();
									hm.put(s2,
											new String(s.getName().substring(
													4,
													s.getName()
															.lastIndexOf('.'))));
									// System.out.println(s2+" added as alias for: "+s.getName());
								}
							}
							// String result = out.toString();
						}
					}
				}
			}
			if (hm.containsKey(command)) {
				command = (String) hm.get(command);

			}
		}
		BasePlugin plugin = null;

		URL[] urls = null;
		File dirfile = new File(classdir + classpre + "" + command + ".class");

		boolean exists1 = dirfile.exists();
		if (exists1) {
			// System.out.println("starting");
			BasePlugin pluginget = PluginLoad.getPlugin(classpre + command);
			String restrict = pluginget.restrict();

			boolean cont = false;
			boolean isop = false;
			boolean ismaker = false;
			boolean isvoice = false;
			User users[] = getUsers(channel);
			User u = null;
			for (User user : users) {
				if (sender.equals(user.getNick())) {
					u = user;
					break;
				}
			}
			if (u != null) {
				if (u.isOp()) {
					isop = true;
				} else if (u.hasVoice()) {
					isvoice = true;
				}
			}

			if (restrict == null || restrict == "none") {
				cont = true;
			} else if (restrict == "op" && isop) {
				cont = true;
			} else if (restrict == "voice" && isvoice) {
				cont = true;
			} else {
				sendNotice(sender,
						"You are not authorized to use this command.");
			}
			if (cont) {
				pluginget.start(this, extra, channel, sender,hostname, usename);
			}
		}
		File dirfile2 = new File(classdir + classpre + "" + command + ".py");

		boolean exists21 = dirfile2.exists();
		if (exists21) {
			// System.out.println("starting");

			PythonInterpreter interp = new PythonInterpreter();
			interp.execfile(dirfile2.toString());
			PyObject ali = interp.get("restrict");
			String restrict = ali.asString();
			boolean cont = false;
			boolean isop = false;
			boolean ismaker = false;
			boolean isvoice = false;
			User users[] = getUsers(channel);
			User u = null;
			for (User user : users) {
				if (sender.equals(user.getNick())) {
					u = user;
					break;
				}
			}
			if (u != null) {
				if (u.isOp()) {
					isop = true;
				} else if (u.hasVoice()) {
					isvoice = true;
				}
			}

			if (restrict == null || restrict.equalsIgnoreCase("none")
					|| restrict.equalsIgnoreCase("null")) {
				cont = true;
			} else if (restrict == "op" && isop) {
				cont = true;
			} else if (restrict == "voice" && isvoice) {
				cont = true;
			} else {
				sendNotice(sender,
						"You are not authorized to use this command.");
			}
			if (cont) {
				interp.set("irc", this);
				interp.set("extra", extra);
				interp.set("usename", usename);
				interp.set("channel", channel);
				interp.set("sender", sender);
				interp.eval("start(channel, sender, usename, extra)");
			}
		}
	}

	protected void onJoin(String channel, String sender, String login,
			String hostname) {

		if (!sender.equalsIgnoreCase(name)) {

			log(channel, sender + " (" + login + "@" + hostname
					+ ") has joined " + channel);
		}
	}

	public void help(String user) {
		File dir2 = new File(classdir);
		File[] list = dir2.listFiles();
		ArrayList al = new ArrayList();
		for (File s : list) {
			if (s.getName().lastIndexOf('.') > 0) {
				if (s.getName().contains("COM_")
						&& s.getName().contains(".class")) {
					BasePlugin plugin = PluginLoad.getPlugin(s.getName()
							.substring(0, s.getName().lastIndexOf('.')));
					if (plugin.hide() == null || !plugin.hide()) {
						al.add(s.getName().substring(4,
								s.getName().lastIndexOf('.')));
					}
				} else if (s.getName().contains("COM_")
						&& s.getName().contains(".py")) {
					PythonInterpreter interp = new PythonInterpreter();

					interp.execfile(s.toString());
					PyObject ali = interp.get("hide");
					String hide = ali.asString();
					if (hide.equalsIgnoreCase("false")) {
						al.add(s.getName().substring(4,
								s.getName().lastIndexOf('.')));
					}
				}
			}
		}
		String fin = "Commands:";
		for (int i = 0; i < al.size(); i++) {
			fin = fin + " " + al.get(i);
		}
		sendNotice(user, fin);
	}

	public void help(String user, String command) {

		File dirfile = new File(classdir + classpre + "" + command + ".class");
		File dirfile2 = new File(classdir + classpre + "" + command + ".py");
		// System.out.println(url2);
		boolean exists = dirfile.exists();
		boolean exists2 = dirfile2.exists();
		if (exists) {
			BasePlugin plugin = PluginLoad.getPlugin(classpre + command);
			if (plugin.hide() == null || !plugin.hide()) {
				sendNotice(user, "" + prefix + plugin.help());
			}
		} else if (exists2) {
			PythonInterpreter interp = new PythonInterpreter();

			interp.execfile(dirfile2.toString());
			PyObject ali = interp.get("hide");
			String hide = ali.asString();

			if (hide.equalsIgnoreCase("false")) {
				PyObject help = interp.get("help");
				String helptext = help.asString();
				sendNotice(user, "" + prefix + helptext);
			}
		}
	}

	protected void onDisconnect() {
		try {
			connect(server);
		} catch (NickAlreadyInUseException e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
		} catch (IOException e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
		} catch (IrcException e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
		}
		System.out.println("server: "+getServer());
		sendMessage("NickServ", "identify " + pass);
		setMessageDelay(500);
		//in.set("bot", this);

		//in.eval("importObject(bot)");

		try {
			FileInputStream fin = new FileInputStream("channels"+getServer()+".dat");
			ObjectInputStream ois = new ObjectInputStream(fin);
			List<String> list = (ArrayList) ois.readObject();

			for (String s : list) {
				al.add(s);
			}

			ois.close();
		} catch (Exception e) {
			e.printStackTrace();
		}
		for (int i = 0; i < al.size(); i++)
			this.joinChannel(al.get(i));
		String input = null;
		try {
			input = (new BufferedReader(new InputStreamReader(System.in)))
					.readLine();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		if (input.equalsIgnoreCase("stop")) {
			System.exit(0);
		} else {

			try {
				in.eval((new BufferedReader(new InputStreamReader(System.in)))
						.readLine());
			} catch (EvalError e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			System.out.println("received");
		}
	}

	protected void onPart(String channel, String sender, String login,
			String hostname) {
		log(channel, sender + " (" + login + "@" + hostname + ") has left "
				+ channel);
	}

	protected void onAction(String sender, String login, String hostname,
			String target, String action) {

	}

	protected void onInvite(String targetNick, String sourceNick,
			String sourceLogin, String sourceHostname, String channel) {
		if (!al.contains(channel)) {
			al.add(channel);

			try {
				System.out.println("serializing list");
				FileOutputStream fout = new FileOutputStream("channels"+getServer()+".dat");
				ObjectOutputStream oos = new ObjectOutputStream(fout);
				oos.writeObject(al);
				oos.close();
				//sendMessage(sourceNick,
						//"I have now joined the requested channel.");

			} catch (Exception e) {
				e.printStackTrace();
				sendMessage(sourceNick,
						"I error'ed when trying to save the channel.");
			}
			joinChannel(channel);
		} else {
			sendMessage(sourceNick, "I should already be on that channel.");
		}
	}

	protected void onKick(String channel, String kickerNick,
			String kickerLogin, String kickerHostname, String recipientNick,
			String reason) {
		log(channel, recipientNick + " was kicked by " + kickerNick + " ("
				+ reason + ")");
		if (recipientNick.equalsIgnoreCase(getNick())) {
			System.out.println("it is me who got kicked!");
			if (al.contains(channel)) {

				try {
					al.remove(channel);
					System.out.println("serializing list");
					FileOutputStream fout = new FileOutputStream("channels"+getServer()+".dat");
					ObjectOutputStream oos = new ObjectOutputStream(fout);
					oos.writeObject(al);
					oos.close();

				} catch (Exception e) {

				}

			}
		}
	}

	public void removechannel(String channel) {
		if (al.contains(channel)) {

			try {
				al.remove(channel);
				System.out.println("serializing list");
				FileOutputStream fout = new FileOutputStream("channels"+getServer()+".dat");
				ObjectOutputStream oos = new ObjectOutputStream(fout);
				oos.writeObject(al);
				oos.close();

			} catch (Exception e) {

			}
			partChannel(channel);
		}
	}

	protected void onPrivateMessage(String sender, String login,
			String hostname, String message) {
		log(sender, sender, login, hostname, message);
		String split[] = message.split(" ");
		if ((split[0].equalsIgnoreCase(prefix + "help") && split.length == 1)
				|| (split[0].equalsIgnoreCase("help") && split.length == 1)
				|| (split[0].toLowerCase().contains(name.toLowerCase())
						&& split[1].toLowerCase()
								.contains("help".toLowerCase()) && split.length == 2)) {
			help(sender);
		} else if ((split[0].equalsIgnoreCase(prefix + "help") && split.length > 1)
				|| (split[0].equalsIgnoreCase("help") && split.length > 1)
				|| (split[0].toLowerCase().contains(name.toLowerCase())
						&& split[1].toLowerCase()
								.contains("help".toLowerCase()) && split.length > 2)) {
			String commandhelp = null;
			if ((split[0].toLowerCase().contains(name.toLowerCase())
					&& split[1].toLowerCase().contains("help".toLowerCase()) && split.length > 2)) {
				commandhelp = split[2].toLowerCase();
			} else {
				commandhelp = split[1].toLowerCase();
			}
			help(sender, commandhelp);
		} else {
			commandexe("x" + message, sender, sender, hostname, false, true);
		}

	}

	public boolean exists(String className) {
		try {
			Class.forName(className);
			return true;
		} catch (ClassNotFoundException exception) {
			return false;
		}
	}

	public static String loadProp(String prop) {
		File file = new File("config.conf");

		// Does the file already exist
		if (!file.exists()) {
			try {
				// Try creating the file
				file.createNewFile();
			} catch (IOException ioe) {
				ioe.printStackTrace();
			}
		}
		try {
			Properties properties = new Properties();
			properties.load(new FileInputStream("config.conf"));

			return properties.getProperty(prop, "pleasereplace");
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			return null;
		}

	}
	public static String loadProp(String prop, String shouldbe) {
		File file = new File("config.conf");

		// Does the file already exist
		if (!file.exists()) {
			try {
				// Try creating the file
				file.createNewFile();
			} catch (IOException ioe) {
				ioe.printStackTrace();
			}
		}
		try {
			Properties properties = new Properties();
			properties.load(new FileInputStream("config.conf"));

			return properties.getProperty(prop, shouldbe);
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			return null;
		}

	}
}
